/*—————————————————————————————————————————————————————————— 路由拦截组件 ——————————————————————————————————————————————————————————*/

import { useNavigate, useLocation } from 'react-router-dom'
import { lazy, useState, Suspense, useEffect, useRef } from 'react'
import { getToken } from '@/utils/userMessage' // 获取内存中token
import { changeLayout } from '@/common/publicStore/reducer' // redux中同步action方法
import { useAppDispatch } from '@/utils/hooks'
import { CSSTransition, SwitchTransition } from 'react-transition-group'

// 接口引入
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
import { routerIntercept } from './interface'

// 名单列表声明引入
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
import config from '@/common/config/config'

export const RouterIntercept: React.FC<routerIntercept> = (props) => {
  // props参数结构
  const { item } = props

  // 状态区域
  // --------------------------------------------------------------------------------------------------------
  const [guard, setGuard] = useState(false) // 路由守卫状态
  const dispatch = useAppDispatch() // 注册修改数据方法
  const location = useLocation() // 获取当前路由信息

  // ref使用
  // --------------------------------------------------------------------------------------------------------
  /**
   * 使用页面状态内存值的原因是，如果直接用state进行控制，则会造成进入页面后登录逻辑判断前会改变标题和内存信息，
   * 会存在不严谨的情况，故进行中间值进行判断
   */
  const guardStorage = useRef(true) // 页面状态内存值,默认打开

  // 路由信息获取
  // --------------------------------------------------------------------------------------------------------
  const navigate = useNavigate() // 跳转函数
  const Pages =
    item.fileAddress &&
    lazy(config.pagesMould[`/src/pages${item.fileAddress}.tsx`] as never) // 动态加载当前页面信息

  // Effect钩子使用区域
  // --------------------------------------------------------------------------------------------------------
  // 拦截逻辑执行钩子
  useEffect(() => {
    // 首先判断是否进行了重定向
    // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    if (!item.navigate) {
      // 执行登录逻辑方法
      isLogin()

      // 如果有重定向的页面则进行重定向
      // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    } else {
      // guardStorage.current = false
      navigate(item.navigate)
    }

    // 如果页面状态内存值是存在的，则进行改变 路由守卫状态
    // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    guardStorage.current && setGuard(guardStorage.current)
  }, [item.fileAddress])

  // layout监听钩子
  // ================================================================================
  useEffect(() => {
    // 根据此时是否开启了layOut模式进行控制全局redux开关
    dispatch(changeLayout(item.isLayOut ?? []))
  }, [JSON.stringify(item.isLayOut)])

  // 标题修改钩子
  // ================================================================================
  useEffect(() => {
    // 如果是允许跳转的情况下
    if (guard) {
      // 同步页面标题
      document.title = item.title ?? ''
    }
  }, [guard, item.title])

  // 配套方法使用
  // --------------------------------------------------------------------------------------------------------
  // 登录内容判断方法
  const isLogin = () => {
    const token = getToken() // 获取token

    // 判断token是否存在
    // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    if (token) {
      // 如果存在token，则在此判断当前的跳转的页面是否是属于 登录成功后不允许访问的页面黑名单 的成员
      if (config.loginBackList.includes(item.name)) {
        // 是的话则进行关闭 页面状态内存值
        // guardStorage.current = falsen

        // 跳转回之前的页面
        navigate(-1)
      }

      // 若是不存在token，则还需要判断是否满足 不需要登录
      // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    } else if (!item.noLogin) {
      // 不满足则进行关闭 页面状态内存值，并跳转到登录页且未关闭原本页面
      // guardStorage.current = false
      navigate('/login', { replace: true })
    }
  }

  // dom元素区域
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  return (
    // 只有当守卫通过时，才能进行跳转
    guard && (
      <Suspense fallback={<>正在加载……</>}>
        <SwitchTransition>
          <CSSTransition
            key={location.pathname}
            timeout={300}
            classNames="page"
            unmountOnExit
          >
            <Pages />
          </CSSTransition>
        </SwitchTransition>
      </Suspense>
    )
  )
}
